/*
 * EventDispatcher.cpp
 *
 *  Created on: 24 nov 2011
 *      Author: Robert
 */

#include "EventDispatcher.h"


void EventDispatcher::addEventListener(const EventType &type, const EventListener &listener, bool useCapture, int priority, bool useWeakReference)
{
	eventListeners[type].insert(std::pair<int,const EventListener &>(priority, listener));
}


void EventDispatcher::dispatchEvent(const Event &event)
{
	// If a tree falls in the woods and no one ...
	if(eventListeners.find(event.type) == eventListeners.end()) {
		return;
	}

	// List of (priority => listener)
	const std::multimap<int, const EventListener &> &listeners = eventListeners[event.type];

	// Loop through from the back (descending order by priority)
	for(std::multimap<int, const EventListener &>::const_reverse_iterator i = listeners.rbegin(); i != listeners.rend(); ++i) {
		// Execute
		const EventListener &listener = i->second;
		listener(event);
	}
}


bool EventDispatcher::hasEventListener(const EventType &type) const
{
	return eventListeners.find(type) != eventListeners.end();
}


void EventDispatcher::removeEventListener(const EventType &type, const EventListener &listener, bool useCapture)
{
	if(eventListeners.find(type) == eventListeners.end()) {
		return;
	}

	// List of (priority => listener)
	std::multimap<int, const EventListener &> &listeners = eventListeners[type];

	// Loop through the listeners; we don't break if we find it because there may be multiple instances
	for(std::multimap<int, const EventListener &>::iterator i = listeners.begin(); i != listeners.end();) {
		// Is it there?
		const EventListener &listener2 = i->second;
		if(&listener2 == &listener) {
			listeners.erase(i++);
		}
		else {
			++i;
		}
	}

	// In case we removed the last one of the type
	if(listeners.empty()) {
		eventListeners.erase(type);
	}
}
